﻿using System;
using System.Linq;
using System.Web.Mvc;
using SlamCms.Common;
using SlamCms.Configuration;
using SlamCms.Data;
using SlamCms.Web;
using SlamCmsDemo.Data;
using SlamCmsDemo.Web.Core;
using SlamCmsDemo.Web.Core.Models;
using SlamCms.SharePointServices;

namespace SlamCmsDemo.Web.Controllers
{
	public class ContentItemController : Controller
	{
		private readonly SlamCmsContext slamCmsContext;
		private readonly Lazy<SharePointDocumentService> sharepointDocumentService;

		public ContentItemController(SlamCmsContext slamCmsContext, Lazy<SharePointDocumentService> sharepointDocumentService)
		{
			this.slamCmsContext = slamCmsContext;
			this.sharepointDocumentService = sharepointDocumentService;
		}

		[HttpGet]
		public ActionResult Details(string contentItemId)
		{
			var contentItem = slamCmsContext.CreateQuery(QueryBuilderOptions.AllZones)
											.FilterContentItemId(contentItemId)
											.IncludeTags()
											.GetFirstOrDefault();

			if (contentItem == null)
				return this.NotFound(); // throw a 404 HttpException

			slamCmsContext.AdministrationBar.SetContentItem(contentItem);

			var model = ContentItemDetailsViewModel.Create(contentItem);

			var tagTree = slamCmsContext.GetTagTree();

			var tagIds = contentItem.Tags.Select(t => t.TagId).ToList();
			
			model.TypeTags = tagTree.FindNodes(x => x.IsTag() && x.BelongsToTagCategory(Constants.TagCategories.Type) && x.Tag.TagId.In(tagIds)).Select(x => x.Tag);
			model.TopicTags = tagTree.FindNodes(x => x.IsTag() && x.BelongsToTagCategory(Constants.TagCategories.Topic) && x.Tag.TagId.In(tagIds)).Select(x => x.Tag);
			model.LocationTags = tagTree.FindNodes(x => x.IsTag() && x.BelongsToTagCategory(Constants.TagCategories.Location) && x.Tag.TagId.In(tagIds)).Select(x => x.Tag);

			// Retrieve related content
			var relatedContent = slamCmsContext.CreateQuery(QueryBuilderOptions.AllZones)
											   .FilterContentTypes<Article, Download, Event>()
											   .FilterRelatedTo(contentItemId)
											   .Take(10)
											   .Get();

			// Retrieve related FAQs
			var relatedFaqs = slamCmsContext.CreateQuery(QueryBuilderOptions.AllZones)
											.FilterContentTypes<Faq>()
											.FilterRelatedTo(contentItemId)
											.Take(5)
											.Get();

			model.RelatedContent = new ContentList()
			{
				Title = "Related Content",
				Items = relatedContent.ToContentList().ToList()
			};

			model.RelatedFaqs = new ContentList()
			{
				Title = "Related Questions",
				Items = relatedFaqs.ToContentList().ToList()
			};

			ViewData.Model = model;
			return View(contentItem.ContentTypeId);
		}

		[HttpGet]
		public ActionResult ContentItemDetailsLink(string contentItemId)
		{
			var contentItem = slamCmsContext.CreateQuery(QueryBuilderOptions.AllZones)
											.FilterContentItemId(contentItemId)
											.GetFirstOrDefault();

			if (contentItem == null)
				return this.NotFound("The element your're looking for does not exist.");

			var url = ConfigurationManager.Environment.DefaultApplication.FrontEndUrl.TrimEnd('/') + "/" + Url.ContentItemDetails(contentItem).TrimStart('/');

			return RedirectPermanent(url);
		}

		[HttpGet]
		public ActionResult Download(string contentItemId)
		{
			var download = slamCmsContext.CreateQuery(QueryBuilderOptions.AllZones)
															.FilterContentItemId(contentItemId)
															.GetFirstOrDefault<Download>();

			if (download == null)
				this.NotFound();

			var sharepointRelativeUrl = Url.AdminRedirectorRelative("document", download.PrimaryContentItemId, new { version = download.IsDraft() ? "draft" : "live" });
			var status = download.IsDraft() ? "draft" : "live";
			var localFileName = "ContentItems\\{0}-{1}.file".F(download.PrimaryContentItemId, status);

			var fileData = this.sharepointDocumentService.Value.Retrieve(sharepointRelativeUrl, localFileName);

			if (fileData == null)
				throw new Exception("There was a problem retrieving the file.");

			return this.FileData(fileData).SetFileDownloadName(download.Url);
		}
	}
}
